iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0

今天要來學習的是 Compose 官方 Thinking in Compose 裡面的 Recomposition (重組):

Recomposition

在命令式(Imperative)的 UI 模型裡,為了改變 UI widget 的狀態或內容,開發者必須呼叫 widget 的 setter 函式來 update 內部的狀態或內容。 在 Compose 的世界裡,** 當有相關的資料有異動的時候,Composable function 會主動被呼叫** 也就是這個 function 被 recomposed(重新組合) 了,這時 UI widgets 會被重新繪製,大家可能會擔心會不會有大量畫面被更新,就如同 React 一樣,Compose framework 會很聰明的只 recompose 需要重置的元件,不會造成不必要的重繪(re-rendering)。

例如:ClickCounter 這個 composable 函式裡面顯示一個 Button:

@Composable
fun ClickCounter(clicks: Int, onClick: () -> Unit) {
    Button(onClick = onClick) {
        Text("I've been clicked $clicks times")
    }
}

每次當這個 Button 被點擊時,caller 更新了 clicks 的值,Compose 呼叫 lambda 函式裡頭的 Text 函式來顯示新的 clicks 值,這樣的過程稱作 Recomposition。 而其他沒有和 clicks 相關的 composable 函式時不會被呼叫。

如果要 rescomposing 整哥 UI tree 的成本是非常高的,會使用更多的算力以及消耗電量。很幸運地,Compose 的 recomposition 是很有智慧的。

Recomposition 是輸入改變時呼叫 composable functions 的過程。發生在函式的輸入改變的時候。

Recomposition 可能會帶來一些 side-effect 而更新畫面,一下動作都是危險的 side-effects:

  • 寫入 shared object 的屬性
  • 更新 ViewModel obserable
  • 更新 shared preferences

為了避免更新畫面的順暢度,請把耗時的工作放在背景執行。
例如,下方的程式碼會建立一個 composable 來更新 SharedPreferences 中的值。這個 composable function 不應從 SharedPreferences 本身讀取或寫入,應該把讀取或寫入的動作放在背景的 ViewModel,Application 邏輯層會適時地更新畫面。

@Composable
fun SharedPrefsToggle(
    text: String,
    value: Boolean,
    onValueChanged: (Boolean) -> Unit
) {
    Row {
        Text(text)
        Checkbox(checked = value, onCheckedChange = onValueChanged)
    }
}

此文件會討論幾個 compose 程式的注意事項:

  • Composable 函式可以按任意順序執行
  • Composable 函式可以同時/平行地被執行
  • Recomposition 會盡可能地忽略沒有相關性的 composable 函式和 lambdas
  • Recomposition是最佳化的,也可以被取消動作
  • 一個 Composable 函式時可以像播放一個動畫那樣頻繁地被更新

接下來會一一地討論這些注意事項。


上一篇
[Day7] Thinking in Compose (一)
下一篇
[Day9] Thinking in Compose (三)
系列文
30天 Android Jetpack Compose 奇幻旅程13
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言